#include "LinkSerialClient.h"
#include "SerialPortInfo.h"
#include <iostream>
#include "lib.h"

#include "../../components.h" //使用info打印信息

using namespace controller;
using namespace itas109;

// 串口的监听事件
class MyListener : public itas109::CSerialPortListener
{
private:
    itas109::CSerialPort *p_sp;

public:
    MyListener(CSerialPort *sp) : p_sp(sp) {};

    void onReadEvent(const char *portName, unsigned int readBufferLen)
    {
        if (readBufferLen > 0)
        {
            char *data = new char[readBufferLen + 1]; // '\0'

            if (data)
            {
                // read
                int recLen = p_sp->readData(data, readBufferLen);
                if (recLen > 0)
                {
                    LinkSerialPort *p = (LinkSerialPort *)p_sp;
                    LinkBuffer buf(data, recLen);
                    std::cout << p->name() << "<<(" << std::to_string(buf.size()) << "):" << p->dump_buffer(&buf) << std::endl;
                    if (p->OnLinkRecv)
                        p->OnLinkRecv(p, &buf, NULL);
                }
                delete[] data;
                data = NULL;
            }
        }
    };
};

LinkSerialPort::LinkSerialPort()
{
    listener = new MyListener(this);
}
LinkSerialPort::~LinkSerialPort()
{
    if (listener != nullptr)
        delete (MyListener *)listener;
    listener = nullptr;
}

// 读写接口
bool LinkSerialPort::open(std::map<std::string, std::string> arg)
{
    if (arg.find("dev") == arg.end())
    {
        std::cout << "LinkSerialPort 未设置 dev" << std::endl;
        return false;
    }
    if (arg.find("baud") == arg.end())
    {
        std::cout << "LinkSerialPort 未设置 baud" << std::endl;
        return false;
    }
    std::string dev = arg["dev"];
    std::string baud = arg["baud"];
    int p = atoi(baud.c_str());
    this->_dev = dev;
    this->_baud = p;

    INFO("zlog info,打开串口设备:%s ,波特率:%d", dev.c_str(), p);

    this->init(dev.c_str(),         // windows:COM1 Linux:/dev/ttyS0
               p,                   // baudrate
               itas109::ParityNone, // parity
               itas109::DataBits8,  // data bit
               itas109::StopOne,    // stop bit
               itas109::FlowNone,   // flow
               4096                 // read buffer size
    );
    this->setReadIntervalTimeout(0);               // read interval timeout 0ms
    this->setByteReadBufferFullNotify(4096 * 0.8); // buffer full notify

    // 1.打开设备
    if (CSerialPort::open() == false)
    {
        std::cout << this->name() << "打开失败,code:" << this->getLastError()
                  << "  message:" << this->getLastErrorMsg() << std::endl;
        if (this->OnLinkDisconnect)
            this->OnLinkDisconnect(this);
        return false;
    }
    else
    {
        if (this->OnLinkConnect)
            this->OnLinkConnect(this);
    }
    // 2.设置监听
    this->connectReadEvent(((itas109::CSerialPortListener *)listener));
    return true;
}
bool LinkSerialPort::close()
{
    CSerialPort::close();
    return CSerialPort::isOpen() == false;
}
int LinkSerialPort::write(char *data, int len, const char *arg)
{
    // std::cout << "是否打开:" << this ->is_open() << "error:" << getLastError() << "msg:" << getLastErrorMsg() <<std::endl;
    LinkBuffer buf(data, len);
    std::cout << this->name() << ">>(" << std::to_string(buf.size()) << "):" << dump_buffer(&buf) << std::endl;
    if (this->OnLinkSend)
        this->OnLinkSend(this, &buf, NULL);
    return CSerialPort::writeData(data, len);
}
// int LinkSerialPort::read(char *dataout, int len)
// {
//     return 0;
// }

// 状态
bool LinkSerialPort::is_open()
{
    return CSerialPort::isOpen();
}
std::string LinkSerialPort::name()
{
    return ("tty[" + this->_dev + ":" + std::to_string(this->_baud) + "]");
}
std::string LinkSerialPort::info()
{
    return "SerialPort";
}